package com.wzcl.app.service.impl;

import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.AlipayTradePagePayRequest;
import com.alipay.api.request.AlipayTradeRefundRequest;
import com.alipay.api.response.AlipayTradeRefundResponse;
import com.wzcl.app.config.MyAliPayConfig;
import com.wzcl.app.dao.model.Course;
import com.wzcl.app.dao.model.OrderDetail;
import com.wzcl.app.dao.model.Orders;
import com.wzcl.app.dao.model.UserCourse;
import com.wzcl.app.dao.repository.CourseRepository;
import com.wzcl.app.dao.repository.OrdersRepository;
import com.wzcl.app.dao.repository.UserCourseRepository;
import com.wzcl.app.model.common.RVO;
import com.wzcl.app.service.AlipayService;
import com.wzcl.app.service.OrderService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.io.UnsupportedEncodingException;
import java.util.*;

/**
 * @author beingven
 * @Description 支付宝支付
 * @createTime 2020年11月17日 12:05:00
 */
@Service
@Slf4j
public class AlipayServiceImpl implements AlipayService {
    @Resource
    private MyAliPayConfig myAliPayConfig;

    @Resource
    private OrdersRepository ordersRepository;

    @Resource
    private UserCourseRepository userCourseRepository;

    @Resource
    private CourseRepository courseRepository;

    @Resource
    private OrderServiceImpl orderService;

    /**
     * 发起支付宝PC支付（网页支付）
     * @param orders 包含订单信息的对象
     */
    @Override
    public RVO createAliPcPay(Orders orders) {
        // 订单号校验
        Orders allByNo = ordersRepository.findAllByOrderNumber(orders.getNo());
        if (null == allByNo || allByNo.getPayState() == 1){
            return RVO.error("该订单不存在或已支付");
        }
        // 金额校验
        if (allByNo.getPayMoney() != orders.getPayMoney()){
            RVO.error("金额不匹配");
        }
        //获得初始化的AlipayClient
        AlipayClient alipayClient =  new  DefaultAlipayClient(
                myAliPayConfig.getGatewayUrl(), myAliPayConfig.getAppId(), myAliPayConfig.getAppPrivateKey(),
                myAliPayConfig.getFormat(), myAliPayConfig.getCharset(), myAliPayConfig.getAliPayPublic(), myAliPayConfig.getSignType());
        // 创建API对应的request
        AlipayTradePagePayRequest alipayRequest =  new  AlipayTradePagePayRequest();
        // 异步回调
        alipayRequest.setNotifyUrl(myAliPayConfig.getPcNotifyUrl());
        // 设置支付参数
        alipayRequest.setBizContent("{" +
            "\"out_trade_no\":"+ orders.getNo() +"," +
            "\"product_code\":\"FAST_INSTANT_TRADE_PAY\"," +
            "\"subject\":\"Wzcl online course purchase\"," +
            "\"total_amount\":"+ orders.getPayMoney() +
            "}");
        //请求
        String result = null;
        try {
            result = alipayClient.pageExecute(alipayRequest).getBody();
            log.info(result);
        } catch (AlipayApiException e) {
            log.info("生成表单失败");
            e.printStackTrace();
        }
        return RVO.success(result);
    }

    /**
     * 创建退款
     * @return
     */
    @Transactional
    @Override
    public Integer createRefund(String orderNumber) {
        //通过订单号查询
        Orders order = ordersRepository.findAllByOrderNumber(orderNumber);
        try {
            AlipayClient alipayClient = new DefaultAlipayClient(myAliPayConfig.getGatewayUrl(), myAliPayConfig.getAppId(),
                    myAliPayConfig.getAppPrivateKey(), "json", myAliPayConfig.getCharset(), myAliPayConfig.getAliPayPublic(), "RSA2");
            AlipayTradeRefundRequest request = new AlipayTradeRefundRequest();
            request.setBizContent("{" +
                    "\"out_trade_no\":\"" + orderNumber + "\"," +
                    "\"refund_amount\":\"" + order.getPayMoney() + "\"," +
                    "\"refund_reason\":\"正常退款\"" +
                    " }");
            AlipayTradeRefundResponse response;
            response = alipayClient.execute(request);
            if (response.isSuccess()) {
                return 200;
            } else {
                //退款失败
                return 500;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return 500;
    }

    /**
     * 支付宝pc支付异步通知
     * @param request 异步请求携带的订单与支付信息
     * @throws UnsupportedEncodingException
     * @throws AlipayApiException
     */
    @Override
    @Transactional
    public String getPcNotify(HttpServletRequest request) throws Exception {
        log.info("===========================异步通知开始===========================");
        //获取支付宝POST过来反馈信息
        Map<String,String> params = new HashMap<>();
        Map<String,String[]> requestParams = request.getParameterMap();
        for (Iterator<String> iter = requestParams.keySet().iterator(); iter.hasNext();) {
            String name = iter.next();
            String[] values = requestParams.get(name);
            String valueStr = "";
            for (int i = 0; i < values.length; i++) {
                valueStr = (i == values.length - 1) ? valueStr + values[i]
                        : valueStr + values[i] + ",";
            }
            //乱码解决，这段代码在出现乱码时使用
            valueStr = new String(valueStr.getBytes("ISO-8859-1"), "utf-8");
            params.put(name, valueStr);
        }
        // 签名校验
        boolean signVerified = AlipaySignature.rsaCheckV1(params, myAliPayConfig.getAliPayPublic(), myAliPayConfig.getCharset(), myAliPayConfig.getSignType()); //调用SDK验证签名
        // 验证成功
        if(signVerified) {
            //交易状态
            String tradeStatus = new String(request.getParameter("trade_status").getBytes("ISO-8859-1"),"UTF-8");
            //订单号
            String orderNumber = new String(request.getParameter("out_trade_no").getBytes("ISO-8859-1"),"UTF-8");
            System.out.println("orderNumber:"+orderNumber);
            //交易状态为成功
            if (tradeStatus.equals("TRADE_SUCCESS")){
                Orders order = ordersRepository.findAllByOrderNumber(orderNumber);
                if(order.getCreateFrom().contains("GROUP")){
                    ordersRepository.setPayStateAndOrdersStateByNo(5, 3, 2, orderNumber);
                    orderService.OrderGroupConsumer(orderNumber);
                    return "SUCCESS";
                }
                //更新订单信息
                ordersRepository.setPayStateAndOrdersStateByNo(1, 3, 2, orderNumber);
                /**
                 * 添加用户课程
                 * 1、通过订单号拿到所有的商品id
                 * 2、根据商品id拿到所有课程
                 * 3、添加课程
                 */
                List<UserCourse> list = new ArrayList<>();
                List<OrderDetail> details = order.getDetails();
                for (int index = 0; index < details.size(); index++) {
                    UserCourse userCourse = new UserCourse();
                    Course course = courseRepository.findAllByCourseId(details.get(index).getCommodity().getResourceId());
                    userCourse.setCourse(course);
                    userCourse.setUserId(order.getUserId());
                    userCourse.setUserPhone(order.getUserPhone());
                    list.add(userCourse);
                }
                userCourseRepository.saveAll(list);
                return "SUCCESS";
            }
        }else {//验证失败
            log.info("签名验证失败");
        }
        throw new Exception("签名验证异常");
    }

}